package bavaria.hightec.banking;

import java.util.Calendar;
import java.util.Date;
import java.util.Timer;
import java.util.TimerTask;

import bavaria.hightec.conditions.DepositAccountConditions;
import bavaria.hightec.conditions.GiroAccountConditions;
import bavaria.hightec.conditions.Conditions.runtime;
import bavaria.hightec.conditions.RateOfInterest;
import bavaria.hightec.exceptions.*;
import bavaria.hightec.time.TimeEmitter;

public class BankImpl implements BankCustomerView,BankAdministration{
	
	private int accountNumber=1000;
	private int [] ref = new int[1000];
	private Account[] account = new Account[1000];
	private int counter;
	public static Calendar c2=Calendar.getInstance();
	public static final int INTERESTTIMEFAKTOR=86400;
	private RateOfInterest rateOfInterest = new RateOfInterest(0.4,11.8); //creditInterest, debitInterest
    
	public BankImpl(){
		TimeEmitter.getInstance();
        Timer interestTimer = new Timer();
        interestTimer.scheduleAtFixedRate(
            	new TimerTask() {
            		public void run()  {
            			BankImpl.this.modifyInterestCalendar();
            			try {
            				BankImpl.this.chargeInterest();
            			} catch (OverCheckException e) {
            				System.out.println(e.getMessage());
            			}
            		}
            	},
            	1000, 
            	(long) TimeEmitter.getPeriod());
	}
	
	private void modifyInterestCalendar(){
		c2.add(Calendar.SECOND, INTERESTTIMEFAKTOR);
	}
	
   public void setConditions(double soll,double hab){
	   rateOfInterest.setDebit(soll);
	   rateOfInterest.setInterest(hab);
	   
   }
   
   public String getGiroConditions(){
	   String s = "Girokonto. Habenzins: " + rateOfInterest.getCreditInterest()+ " " + "Sollzins: " +rateOfInterest.getDebitInterest() + " Bonitaeten: " +GiroAccountConditions.CreditHistory.THREE+" "+ GiroAccountConditions.getCreditHistory(GiroAccountConditions.CreditHistory.THREE) +" "+ GiroAccountConditions.CreditHistory.TWO + " " + GiroAccountConditions.getCreditHistory(GiroAccountConditions.CreditHistory.TWO)+" "+ GiroAccountConditions.CreditHistory.ONE + " " + GiroAccountConditions.getCreditHistory(GiroAccountConditions.CreditHistory.ONE);
	   return s;
   }
   
   public String getDepositConditions(){
	   String t = "Festgeldkonto. Laufzeit/Zins : " + runtime.THREE +" "+DepositAccountConditions.getCreditInterest(runtime.THREE)+" "+ runtime.SIX +" "+DepositAccountConditions.getCreditInterest(runtime.SIX)+" "+ runtime.TWELVE +" "+DepositAccountConditions.getCreditInterest(runtime.TWELVE);
	   return t;
   }
    
    	
	public String createGiroAccount(String name){
		if(counter<account.length){
			GiroAccountConditions konditionen = new GiroAccountConditions();
			Date creation = TimeEmitter.getInstance().getCalendar().getTime();
			account[counter]=new GiroAccount(creation,konditionen,rateOfInterest,accountNumber,name);
			ref[counter]=accountNumber;
			String s = "Girokonto am " + creation+ " erstellt. Kontonr: " + accountNumber + " Besitzer: " + name;
			accountNumber++;
			counter++;
			return s;
		}
		else
			throw new MaximumAccountException("Maximale Kontoanzahl erreicht!");
		
	}
	
	public String createDepositAccount(String name,runtime runtime){
		if(counter<account.length){
			
			DepositAccountConditions konditionen= new DepositAccountConditions(runtime);
			Date creation= TimeEmitter.getInstance().getCalendar().getTime();
			account[counter]=new DepositAccount(creation,konditionen,accountNumber,name);
			ref[counter]=accountNumber;
			String s = "Festgeldkonto am " + creation+" erstellt. Kontonr: " + accountNumber + " Besitzer: " + name;
			accountNumber++;
			counter++;
			return s;
		}
		else
			throw new MaximumAccountException("Maximale Kontoanzahl erreicht!");
		
	}
		
	
	
	public int searchAccountNumber(int kontonr){
		int stelle = kontonr-1000; // kontonr - 1000(Startkontonr)
		if(stelle<account.length)
			return stelle;
		else
			throw new UnknownAccountException("Kontonummer ist nicht bekannt!");
	}

	
	public long balance(int accountNumber){
		return account[searchAccountNumber(accountNumber)].getBalance();
		
		
	}


	public void withdraw(int kontonr, Money betrag,String grund)throws OverCheckException {
		account[searchAccountNumber(kontonr)].debitEntry(betrag, grund);
		
	}

	
	public void fund(int accountNumber, Money amount,String matter) throws OverCheckException {
		account[searchAccountNumber(accountNumber)].creditEntry(amount, matter);
	}
	
	
	public void transaction(int accountNumber, int accountOfDestination, Money amount,String matter) throws OverCheckException {
		account[searchAccountNumber(accountNumber)].debitEntry(amount, matter);
		account[searchAccountNumber(accountOfDestination)].creditEntry(amount, matter);
				
	}
	
	public void chargeInterest() throws OverCheckException{
		for(int x=0;x<account.length;x++){
			if(account[x]!=null)
			account[x].chargeInterest();
		}
	}
	
	public void list(){
		for(int x=0;x<account.length;x++){
			if(account[x]!=null)
			System.out.println(account[x].toString());
		}
	}	
	
	public void accountString(int accountNumber){
		account[searchAccountNumber(accountNumber)].statement();
	}



}



	

